package study.ct.com.retrofit_rxjava.net.retrofit;

import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.CookieJar;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


/**
 * Created by ct on 2017/10/11 0011.
 */

public class NetMgr {
    private final  long connnectTimeoutMills=10*1000l;//默认链接时间，设置在 provider中设置
    private final long defaultReadTimeOut=10*1000l;//同上

    private static final String TAG = "NetMgr";


    public static NetMgr instance;
    public NetProvider mProvider=null;
    public Map<String,Retrofit> retrofitMap=new HashMap<>();//缓存访问过的 retrofit
    public Map<String,NetProvider> netProviderMap=new HashMap<>();//缓存设置过的provider；
    public Map<String,OkHttpClient> clientMap=new HashMap<>();// 缓存 url 对应的client

    public static NetMgr getInstance(){
        if (instance==null){
            synchronized (NetMgr.class){
                if (instance==null){
                    instance=new NetMgr();
                }
            }
        }
        return  instance;
    }


    //create service
    public <S> S get(String baseUrl,Class<S> service){

        return getInstance().getRetrofit(baseUrl).create(service);
    }

    public Retrofit getRetrofit(String baseUrl, NetProvider provider) {
        if (empty(baseUrl)) {
            throw new IllegalStateException("baseUrl can not be null");
        }
        if (retrofitMap.get(baseUrl) != null) {
            return retrofitMap.get(baseUrl);
        }

        if (provider == null) {
            provider = netProviderMap.get(baseUrl);
            if (provider == null) {
                provider = mProvider;
            }
        }

        checkProvider(provider);

        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .create();

        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(getClient(baseUrl, provider))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(gson));

        Retrofit retrofit = builder.build();
        retrofitMap.put(baseUrl, retrofit);
        netProviderMap.put(baseUrl, provider);

        return retrofit;


    }

    public OkHttpClient getClient(String baseUrl,NetProvider provider){
        if (empty(baseUrl)){
            throw new IllegalStateException("baseUrl can not be null");
        }

        if (clientMap.get(baseUrl)!=null){
            return clientMap.get(baseUrl);
        }

        if (provider==null){
            provider = netProviderMap.get(baseUrl);
            if (provider==null){
                provider=mProvider;
            }
        }

        checkProvider(provider);

        OkHttpClient.Builder builder=new OkHttpClient.Builder();
        builder.connectTimeout(provider.configConnectTimeoutSecs()!=0?
                provider.configConnectTimeoutSecs():connnectTimeoutMills, TimeUnit.SECONDS);
        builder.readTimeout(provider.configReadTimeoutSecs() != 0 ?
                provider.configReadTimeoutSecs() : defaultReadTimeOut, TimeUnit.SECONDS);
        builder.writeTimeout(provider.configWriteTimeoutSecs() != 0
                ? provider.configReadTimeoutSecs() : defaultReadTimeOut, TimeUnit.SECONDS);

        CookieJar cookieJar=provider.configCookie();

        if (cookieJar!=null){
            builder.cookieJar(cookieJar);
        }

        provider.configHttps(builder);

        RequestHandler handler=provider.configHandler();
        if (handler!=null){
            builder.addInterceptor(new NetInterceptor(handler));
        }

        Interceptor[] interceptors=provider.configInterceptors();
        if (!empty(interceptors)){//添加拦截器
            for (Interceptor interceptor:interceptors){
                builder.addInterceptor(interceptor);
            }
        }

        if (provider.configLogEnable()) {//添加log 拦截器
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(
                    new HttpLoggingInterceptor.Logger(){

                @Override
                public void log(String message) {
                    Log.i(TAG, "log: Retrofit=>"+message);
                }
            });
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            builder.addInterceptor(loggingInterceptor);
        }

        OkHttpClient client=builder.build();
        clientMap.put(baseUrl, client);
        netProviderMap.put(baseUrl, provider);

        return client;

    }

    public Retrofit  getRetrofit(String baseUrl){

        return getRetrofit(baseUrl, null);
    }




    public void checkProvider(NetProvider provider){

        if (provider==null){
            throw new IllegalStateException("must register provider first");
        }
    }

    public void registerProvider(NetProvider provider){
        this.mProvider=provider;
    }

    //将 链接对应的provider 写入缓存
    public void registerProvider(String baseUrl,NetProvider provider){
        getInstance().netProviderMap.put(baseUrl, provider);
    }

    public NetProvider getDefaultProvider(){
        return  mProvider;
    }

    public void clearCache(){
        getInstance().retrofitMap.clear();
        getInstance().clientMap.clear();
    }

    public Map<String,Retrofit> getRetrofitMap(){
        return retrofitMap;
    }
    public Map<String,OkHttpClient>getClientMap(){
        return clientMap;
    }

    public boolean empty(String url){
        return url==null||url.isEmpty();
    }

    public boolean empty(Interceptor[] interceptors){
        return  interceptors==null||interceptors.length==0;
    }

}
